﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Browser;
using System.Windows.Media;

using SBPweb.RIA.Client.Contracts.Base;
using SBPweb.RIA.Client.Contracts.Models;

using SBPweb.RIA.Client.Controls.Base;

namespace SBPweb.RIA.Client.Controls.Models
{

    public class PluginContainerModel : DependencyObjectBase, IPluginContainerModel
    {

        #region Fields

        private HtmlElement containerElement;

        #endregion

        #region Constructor logic

        public PluginContainerModel(HtmlElement element)
        {
            containerElement = element;
        }

        public PluginContainerModel(string containerId)
            : this(HtmlPage.Document.GetElementById(containerId))
        {
        }

        #endregion

        #region Properties

        public bool IsVisible
        {
            get
            {
                return containerElement.Parent.CssClass.Contains("Visible");
            }
            set
            {
                containerElement.Parent.CssClass = string.Format("div{0}{1}", Id.Replace("sc", string.Empty), value ? "Visible" : "Hidden");
            }
        }

        public string Id
        {
            get
            {
                return containerElement.Id;
            }
        }

        public HtmlElement Container
        {
            get
            {
                return containerElement;
            }
        }

        public UIElement MainVisual
        {
            get;
            set;
        }

        #endregion

        #region Methods

        public TInterface FetchScriptableModel<TInterface, TProxy>(string name)
            where TInterface : IScriptableModel
            where TProxy : ScriptableModelProxyBase, TInterface
        {
            ScriptObject sO = containerElement.Children[0].GetProperty("Content") as ScriptObject;
            if (sO == null)
            {
                return default(TInterface);
            }
            sO = sO.GetProperty(name) as ScriptObject;
            if (sO == null)
            {
                return default(TInterface);
            }

            TProxy proxy = (TProxy)Activator.CreateInstance(typeof(TProxy), sO);

            return proxy;
        }

        public void Destroy()
        {
            HtmlElement element = containerElement.Children[0] as HtmlElement;
            containerElement.RemoveChild(element);
            containerElement.Parent.RemoveChild(containerElement);
            containerElement = null;
        }

        public void Move(double? left, double? top)
        {
            Move((int)left, (int)top);
        }

        public void Move(int? left, int? top)
        {
            if (left.HasValue)
            {
                containerElement.SetStyleAttribute("left", string.Format("{0}px", left));
            }
            if (top.HasValue)
            {
                containerElement.SetStyleAttribute("top", string.Format("{0}px", top));
            }
        }

        public void Resize(double? width, double? height)
        {
            Resize((int)width, (int)height);
        }

        public void Resize(int? width, int? height)
        {
            if (width.HasValue)
            {
                containerElement.SetStyleAttribute("width", string.Format("{0}px", width));
            }
            if (height.HasValue)
            {
                containerElement.SetStyleAttribute("height", string.Format("{0}px", height));
            }
        }

        public void ResizeToMinimum(double? width, double? height)
        {
            Size size;
            if (MainVisual != null)
            {
                size = MainVisual.RenderSize;
            }
            else
            {
                size = ExtendableApplication.Current.RootVisual.RenderSize;
            }
            if (width.HasValue && width.Value > size.Width)
            {
                size.Width = width.Value;
            }
            if (height.HasValue && height.Value > size.Height)
            {
                size.Height = height.Value;
            }
            double w = size.Width + 6;
            double h = size.Height + 6;
            Resize(w, h);
        }

        public void ResizeToMaximum()
        {
            Resize(DOMContextModel.SingletonInstance.Screen.ClientWidth, DOMContextModel.SingletonInstance.Screen.ClientHeight);
        }

        public T FindElement<T>(string name)
            where T : FrameworkElement
        {
            List<FrameworkElement> elements = new List<FrameworkElement>();
            FindDownInTree(elements, ExtendableApplication.Current.RootVisual, typeof(T), name);
            if (elements.Count == 0)
            {
                return default(T);
            }
            return (T)elements[0];
        }

        private void FindDownInTree(List<FrameworkElement> elements, DependencyObject parent, Type controlType, string name)
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
            {
                FrameworkElement visual = VisualTreeHelper.GetChild(parent, i) as FrameworkElement;
                if (controlType.IsInstanceOfType(visual) && visual.Name == name)
                {
                    elements.Add(visual);
                }
                if (visual != null)
                {
                    FindDownInTree(elements, visual, controlType, name);
                }
            }
        }

        #endregion

    }

    public class PluginContainerModelCollection : KeyedCollection<string, IPluginContainerModel>
    {

        protected override string GetKeyForItem(IPluginContainerModel item)
        {
            return item.Id;
        }

    }

}